package com.ffcs.crmd.tsp.core.netty;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ffcs.crmd.tsp.api.dto.netty.RemotingCommand;
import com.ffcs.crmd.tsp.common.constant.LoggerName;
import com.ffcs.crmd.tsp.core.util.RemotingUtil;
import com.ffcs.crmd.tsp.core.util.XmlUtil;

/**
 * 
 * 功能说明:自定义的netty通信体的解码
 *
 * @author ZHONGFUHUA
 * 
 * @Date 2016年1月18日 下午3:03:26
 *
 *
 * 版本号  |   作者   |  修改时间   |   修改内容
 *
 */
public class NettyDecoder extends LengthFieldBasedFrameDecoder {
    /**
     * 日志
     */
    private final Logger log = LoggerFactory.getLogger(LoggerName.RemotingLoggerName);
    
    public NettyDecoder() {
        super(Integer.MAX_VALUE, 0, 4, 0, 4);
    }
    
    @Override
    protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
        ByteBuf frame = null;
        try {
            frame = (ByteBuf) super.decode(ctx, in);
            if (null == frame) {
                return null;
            }
            byte[] decoded = new byte[frame.readableBytes()];
            frame.readBytes(decoded);
            return (RemotingCommand) XmlUtil.fromXml(new String(decoded), RemotingCommand.class);
        } catch (Throwable e) {
            log.error("NETTY SERVER: decoder data channel[{}] exception ", ctx.channel(), e);
            RemotingUtil.closeChannel(ctx.channel());
        } finally{
            if (null != frame) {
                boolean result = frame.release();
                if(!result){
                    log.error("NETTY SERVER: decoder data channel[{}] realse fail.", ctx.channel());
                }
            }
        }
        return null;
    }
    
}
